package org.shangrila.bme.mb;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.model.SelectItem;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;
import org.shangrila.app.sys.cfg.AppInitInfo;
import org.shangrila.app.sys.shiro.SecUtil;
import org.shangrila.bme.eo.AppFileInfo;
import org.shangrila.bme.eo.BmeContPurch;
import org.shangrila.bme.eo.BmeMaterial;
import org.shangrila.bme.eo.BmePurchDetail;
import org.shangrila.bme.eo.BmePurchOrder;
import org.shangrila.bme.eo.BmeReceipt;
import org.shangrila.bme.eo.BmeReceiptDetail;
import org.shangrila.bme.eo.BmeSupplier;
import org.shangrila.bme.eo.BmeWfmService;
import org.shangrila.comm.dao.DbAccess;
import org.shangrila.comm.helper.IDHelper;
import org.shangrila.wfm.core.WfmEngine;
import org.shangrila.wfm.eo.WfmTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;

@Named
@SessionScoped
public class ReceiptMB implements Serializable {
	private static final long serialVersionUID = -533146464217112L;
	private final Logger log = LoggerFactory.getLogger(this.getClass());

    private BmeReceipt io = new BmeReceipt();//录入    
	private List<BmeReceipt> vo = new ArrayList<BmeReceipt>(); //查询

	private List<BmeReceiptDetail> vod = new ArrayList<BmeReceiptDetail>(); //详情
	private BmeReceiptDetail selectedd = new BmeReceiptDetail();//录入以及选择详情信息	
	private List<BmePurchOrder> bmePurchOrders; 	
	private BmePurchOrder selectedPurchOrder = new BmePurchOrder(); 

	private List<BmePurchDetail> bmePurchDetails; 	
	private BmePurchDetail selectedPurchDetail = new BmePurchDetail(); 
	private List<BmePurchDetail> selectedPurchDetails; 	

	private BmeMaterial selectedMaterial = new BmeMaterial(); 
	private BmeSupplier selectedSupplier = new BmeSupplier(); 

	//获取相关数据字典
	private List<SelectItem> itemsStatus = AppInitInfo.getDropdownList("ReceiptStatus"); 

	private String operator;
	private String purchId="";
	private String qid="";
	private String processName="wf_fhd";
	private WfmTask selectedTask;
	
	private String uploadedFile="";
	private String uploadedFileImage="";

	//附件上传页面参数传递
	private String uploadForType="3";
	private String uploadForId="0";
	private String uploadForName="0";

	@Inject
	private DbAccess db;
	@Inject
	BmeCommEntityService bmeCommEntityService; 
	@Inject
	private AttachUploadMB attachUploadMB;
	
	@PostConstruct
    public void init() {
		log.info("@PostConstruct..."+this.getClass());
		try{
			operator = SecUtil.getCachedShiroUser().getUserno();
			//供应商只能看到自己的订单（合同）
			String sql = "SELECT m FROM BmeSupplier m WHERE m.operator=?1";
			List<BmeSupplier> ls = db.findBySql(sql,new Object[]{operator});
			if(ls.size()>0) {
				selectedSupplier = ls.get(0);
			}
		}
		catch(Exception ex){
			operator="bme";
		}
		
		newIo();		

    }

    public void initdata() {
		String sql = "SELECT m FROM BmePurchOrder m WHERE m.bmeSupplier.id=?1 AND m.status='3'";
		bmePurchOrders = db.findBySql(sql,new Object[]{selectedSupplier.getId()});
    }    

    public void newIo() {
    	initdata();
    	io = new BmeReceipt();
    	io.setId(IDHelper.genStrID(20));
    	io.setStatus("1");
    	selectedPurchOrder = new BmePurchOrder(); 
    	vo = new ArrayList<BmeReceipt>();
    	vod = new ArrayList<BmeReceiptDetail>();
    	attachUploadMB.setVoList(new ArrayList<AppFileInfo>());
    	attachUploadMB.setUploadedFileImage("");
    }    

	//null
	public String nullAction() {
		return null;
	}
	
	//提交流程
	public String commitWfmAction() {
		if(!validDetailAction()) {
			return null;
		}
		genShipAmount();//修改合同已下单数
		
		//制单状态才能提交
		if(null==io.getId() || !"1".equals(io.getStatus())) {
			AppInitInfo.showMessage("发货单提交流程", "制单状态单据才可以提交流程");
			return null;
		}
		//提交流程
		//流程参数
		Map<String, Object> args = new HashMap<String, Object>();	
		//业务编号作为WFM实例的serviceNo
		args.put(AppInitInfo.APP_BUSINESS_NO, io.getId());  	
		//下一个流程节点处理工号，all可以代表所有操作工号，只要有此流程角色即可
		args.put(AppInitInfo.APP_OPERATOR,selectedPurchOrder.getBmeContract().getPm());	//项目经理		
		args.put(AppInitInfo.APP_BUSINESS_TYPE, uploadForType);		   //自定义业务参数：业务类型
		//operator="bme";  					   //发起本流程任务操作的工号

		WfmEngine engine = new WfmEngine();//流程引擎
		//启动流程实例
		engine.startService(engine.getWfmdao().findProcessByName(processName).get(0), operator, args);
		
		//填写业务流程日志信息
		BmeWfmService bws = new BmeWfmService();
		bws.setId(IDHelper.genStrID(24));
		bws.setBusinessId(io.getId());
		bws.setBusinessType(uploadForType);
		bws.setCreateTime(new Date());
		bws.setOperator(operator);
		bws.setProcessName(processName);
		bws.setServiceNo(io.getId());
		io.setStatus("2");
		db.begin();
		db.insert(bws);
		db.update(io);
		db.commit();
		AppInitInfo.showMessage("发货单提交流程", "处理成功");
		
		return null;
	}
    
	//新增
    public void onAdd() {   
    	newIo();
    	AppInitInfo.showMessage("新增发货单", "处理成功");
    }
    //保存
	public String saveAction() {
		
		db.beginTransaction();
		io.setBmeContract(selectedPurchOrder.getBmeContract());
		io.setSupplier(selectedSupplier.getId());
		io.setContName(selectedPurchOrder.getContName());
		io.setBmePurchOrder(selectedPurchOrder);
		io.setCreateTime(new Date());
		io.setOperator(operator);
		db.insert(io);
		db.commitTransaction();
		
		AppInitInfo.showMessage("发货单录入", "处理成功");
		uploadForId=io.getId();
		uploadForName=io.getContName();
		return null;
	}
	
    //选择合同下的采购订单
    public void onPurchOrderSelected(SelectEvent event) {
     	//selectedPurchOrder = (selectedPurchOrder) event.getObject(); 
    	//this.selectedSupplier = selectedPurchOrder.getBmeSupplier();    	
    	io.setAddress(selectedPurchOrder.getShippingAddress());
    	io.setBmeContract(selectedPurchOrder.getBmeContract());
    	io.setBmePurchOrder(selectedPurchOrder);
    	io.setConsignee(selectedPurchOrder.getConsignee());
    	io.setContName(selectedPurchOrder.getContName());
    	io.setPhone(selectedPurchOrder.getPhone());
    	io.setSupplier(selectedSupplier.getId());
    	bmePurchDetails = selectedPurchOrder.getBmePurchDetails();
    }

	//验证详单操作的有效性
	public boolean validDetailAction(){
		if(null==io.getCreateTime()) {
			AppInitInfo.showMessage("warn","操作无效", "请确保单据主体信息已经保存");
			return false;
		}
		else
			return true;
	}
	
    //清单选择录入保存
	public String saveDetail() {	
		if(!validDetailAction()) {
			return null;
		}
		if(null==selectedPurchDetails || selectedPurchDetails.size()<=0){
			AppInitInfo.showMessage("info","操作无效", "没有选择清单物料");
			return null;
		}
			
		List<BmeReceiptDetail> bpdList = new ArrayList<BmeReceiptDetail>();
		for(BmePurchDetail bpd:selectedPurchDetails) {
			selectedd = new BmeReceiptDetail();
			selectedd.setId(IDHelper.genStrID(20));
			selectedd.setBmeReceipt(io);			
			selectedd.setBmeMaterial(bpd.getBmeMaterial());
			selectedd.setId(IDHelper.genStrID(20));
	     	selectedd.setMdesc(bpd.getMdesc());
	     	selectedd.setMunit(bpd.getMunit());
	     	selectedd.setMquantity(bpd.getMquantity());
	     	selectedd.setMamount(bpd.getMamount());

	     	selectedd.setSpeci(bpd.getSpeci());
	     	selectedd.setProcessQuantity(bpd.getProcessQuantity());
	     	selectedd.setProcessSpeci(bpd.getProcessSpeci());
	     	selectedd.setProcessTeck(bpd.getProcessTeck());
	     	
			selectedd.setCreateTime(new Date());
			selectedd.setOperator(operator);
			bpdList.add(selectedd);
		}
		try {
			db.beginTransaction();
			for(BmeReceiptDetail bcp:bpdList) {
				db.insert(bcp);
			}
			db.commitTransaction();
			
			vod.addAll(bpdList);
			io.setBmeReceiptDetails(vod);
			AppInitInfo.showMessage("新增详情录入", "处理成功");
			selectedPurchDetails = null;
			}catch(Exception e) {			
				AppInitInfo.showMessage("error","新增详情失败", "请确保单据主体信息已经保存");
				log.error(e.getLocalizedMessage());
				try {
					db.rollbackTransaction();
				}catch(Exception ex) {	}
			} 	
		return null;
	}
	
	//删除
    public String delDetail() {
    	vod.remove(selectedd);
		db.beginTransaction();
		db.delete(selectedd);
		db.commitTransaction();

        AppInitInfo.showMessage("删除记录", "处理成功");
        return null;
    }
	
	//编辑
    public void onRowEdit(RowEditEvent event) {
    	selectedd = vod.get(vod.indexOf((BmeReceiptDetail) event.getObject()));
    	if(!validQuantity(selectedd)) {
    		AppInitInfo.showMessage("详单数量修改失败", "发货数量不能大于采购数量");	
    		return;
    	}
    	db.beginTransaction();
    	db.update(selectedd);
    	db.commitTransaction();
    	AppInitInfo.showMessage("详单修改", "处理成功");
    }
    
    //发货量不能大于订单中的采购量
    public boolean validQuantity(BmeReceiptDetail brd) {
    	for(BmePurchDetail bpd:bmePurchDetails) {
    		if(bpd.getBmeMaterial().getId().equals(brd.getBmeMaterial().getId())) {
    			if(null!=bpd.getMquantity() && null!=brd.getMquantity() && (brd.getMquantity().intValue() > bpd.getMquantity().intValue()) ) {
    				return false;
    			}
    			else
    				break;
    		}
    	}
    	return true;
    }
    
    public void onRowCancel(RowEditEvent event) {

    }
    
	//genShipAmount 修改合同采购清单已发货量  订单下已发货金额
    public void genShipAmount() {
		if(!validDetailAction()) {
			return ;
		}
    	BigDecimal sumMoney = new BigDecimal(0);
		//从Detail表生成修改BmeContPurch对应的已发货量
		db.beginTransaction();
		for(BmeReceiptDetail brd:vod) {
			sumMoney = sumMoney.add(null==brd.getMamount() ? new BigDecimal(0) : brd.getMamount());//订单金额
			
			for(BmeContPurch bcp:selectedPurchOrder.getBmeContract().getBmeContPurches()) { //修改BmeContPurch对应的已发货量
				if(bcp.getBmeMaterial().getId().equalsIgnoreCase(brd.getBmeMaterial().getId())) {
					bcp.setQtyShipped(brd.getMquantity());
					bcp.setQtyTransitted(bcp.getQuantity().subtract(bcp.getQtyShipped()));
					db.update(bcp);					
				}
			}
			for(BmePurchDetail bcd:selectedPurchOrder.getBmePurchDetails()) { //修改BmePurchDetail对应的已发货量
				if(bcd.getBmeMaterial().getId().equalsIgnoreCase(brd.getBmeMaterial().getId())) {
					bcd.setSquantity(brd.getMquantity());					
					db.update(bcd);					
				}
			}
		}
		io.getBmePurchOrder().setShippedAmount(sumMoney); //订单下已发货金额
		io.getBmePurchOrder().setUnshippedAmount(null==io.getBmePurchOrder().getAmount()? new BigDecimal(0) : io.getBmePurchOrder().getAmount().subtract(sumMoney));
		db.update(io.getBmePurchOrder());
		db.commitTransaction();
		AppInitInfo.showMessage("生成合同采购清单已发货量", "处理成功");
    }
		
	public BmeReceipt getIo() {
		return io;
	}

	public void setIo(BmeReceipt io) {
		this.io = io;
	}

	public List<BmeReceiptDetail> getVod() {
		return vod;
	}

	public void setVod(List<BmeReceiptDetail> vod) {
		this.vod = vod;
	}

	public BmeReceiptDetail getSelectedd() {
		return selectedd;
	}

	public void setSelectedd(BmeReceiptDetail selectedd) {
		this.selectedd = selectedd;
	}

	public BmeSupplier getSelectedSupplier() {
		return selectedSupplier;
	}

	public void setSelectedSupplier(BmeSupplier selectedSupplier) {
		this.selectedSupplier = selectedSupplier;
	}


	public BmeMaterial getSelectedMaterial() {
		return selectedMaterial;
	}

	public void setSelectedMaterial(BmeMaterial selectedMaterial) {
		this.selectedMaterial = selectedMaterial;
	}

	public String getPurchId() {
		return purchId;
	}

	public void setPurchId(String purchId) {
		this.purchId = purchId;
	}

	public String getUploadedFile() {
		return uploadedFile;
	}

	public void setUploadedFile(String uploadedFile) {
		this.uploadedFile = uploadedFile;
	}

	public String getUploadedFileImage() {
		return uploadedFileImage;
	}

	public void setUploadedFileImage(String uploadedFileImage) {
		this.uploadedFileImage = uploadedFileImage;
	}

	public String getUploadForType() {
		return uploadForType;
	}

	public void setUploadForType(String uploadForType) {
		this.uploadForType = uploadForType;
	}

	public String getUploadForId() {
		return uploadForId;
	}

	public void setUploadForId(String uploadForId) {
		this.uploadForId = uploadForId;
	}

	public String getUploadForName() {
		return uploadForName;
	}

	public void setUploadForName(String uploadForName) {
		this.uploadForName = uploadForName;
	}

	public String getQid() {
		return qid;
	}

	public void setQid(String qid) {
		this.qid = qid;
	}

	public List<BmePurchOrder> getBmePurchOrders() {
		return bmePurchOrders;
	}

	public void setBmePurchOrders(List<BmePurchOrder> bmePurchOrders) {
		this.bmePurchOrders = bmePurchOrders;
	}

	public BmePurchOrder getSelectedPurchOrder() {
		return selectedPurchOrder;
	}

	public void setSelectedPurchOrder(BmePurchOrder selectedPurchOrder) {
		this.selectedPurchOrder = selectedPurchOrder;
	}

	public List<BmePurchDetail> getBmePurchDetails() {
		return bmePurchDetails;
	}

	public void setBmePurchDetails(List<BmePurchDetail> bmePurchDetails) {
		this.bmePurchDetails = bmePurchDetails;
	}

	public BmePurchDetail getSelectedPurchDetail() {
		return selectedPurchDetail;
	}

	public void setSelectedPurchDetail(BmePurchDetail selectedPurchDetail) {
		this.selectedPurchDetail = selectedPurchDetail;
	}

	public List<BmeReceipt> getVo() {
		return vo;
	}

	public void setVo(List<BmeReceipt> vo) {
		this.vo = vo;
	}

	public WfmTask getSelectedTask() {
		return selectedTask;
	}

	public void setSelectedTask(WfmTask selectedTask) {
		this.selectedTask = selectedTask;
	}

	public List<BmePurchDetail> getSelectedPurchDetails() {
		return selectedPurchDetails;
	}

	public void setSelectedPurchDetails(List<BmePurchDetail> selectedPurchDetails) {
		this.selectedPurchDetails = selectedPurchDetails;
	}

	public List<SelectItem> getItemsStatus() {
		return itemsStatus;
	}

	public void setItemsStatus(List<SelectItem> itemsStatus) {
		this.itemsStatus = itemsStatus;
	}
	
}